/*
 * @Description: 二次加密工具函数
 * @Author: 0001100986/LiuShuai
 * @Date: 2021-06-22 14:09:49
 * @LastEditTime: 2021-07-16 09:37:23
 * @LastEditors: 0001100986/LiuShuai
 */
let Buffer = require('buffer').Buffer;
import axios from 'axios';
import crypto from 'crypto-browserify';

// gateway 重启时，重新登录会刷新网页并清空 pubKey
let pubKey = '';

const getCsrf = () => {
  let name = 'XSRF-TOKEN=';
  let ca = document.cookie.split(';');
  for (let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) === ' ') { c = c.substring(1) }
    if (c.indexOf(name) !== -1) return c.substring(name.length, c.length);
  }
  return '';
};

async function getPubKey () {
  if (pubKey) {
    return pubKey;
  }
  return axios.get('/action/key/pub').then(result => {
    pubKey = '-----BEGIN PUBLIC KEY-----\n' + JSON.stringify(result.data).substring(1, JSON.stringify(result.data).length - 1) + '\n-----END PUBLIC KEY-----';
    return pubKey;
  });
}

const CryptoUtil = {
  getKey: getPubKey,
  decrypt: (text, key) => {
    if (key && key.startsWith('-----')) {
      // 不对称加密，要求 key 是 pem 格式的公钥或私钥
      const ko = { key: key, padding: crypto.constants.RSA_PKCS1_PADDING };
      const func = key.indexOf('PUBLIC') > 0 ? crypto.publicDecrypt : crypto.privateDecrypt;
      const decrypt = func(ko, Buffer.from(text, 'base64'));
      return decrypt.toString();
    } else {
      // 对称加密
      const decipher = crypto.createDecipher('aes-128-ecb', key || getCsrf());
      decipher.update(text, 'base64');
      return decipher.final('utf8');
    }
  },
  encrypt: (text, key) => {
    if (key && key.startsWith('-----')) {
      // 不对称加密，要求 key 是 pem 格式的公钥或私钥
      const ko = { key: key, padding: crypto.constants.RSA_PKCS1_PADDING };
      const func = key.indexOf('PUBLIC') > 0 ? crypto.publicEncrypt : crypto.privateEncrypt;
      const encrypt = func(ko, Buffer.from(text));
      return encrypt.toString('base64');
    } else {
      // 对称加密
      const cipher = crypto.createCipher('aes-128-ecb', key || getCsrf());
      cipher.update(text);
      return cipher.final('base64');
    }
  },
  hash: (text, algorithm) => {
    const hash = crypto.createHash(algorithm || 'sha256');
    hash.update(text);
    return hash.digest('base64');
  },
  hmac: (text, secret, algorithm) => {
    const hmac = crypto.createHmac(algorithm || 'sha1', secret);
    hmac.update(text);
    return hmac.digest('base64');
  }
};

export default CryptoUtil;
